import * as xlsx from 'xlsx';
import {WorkBook} from 'xlsx';

export const filterUrl = (url: any) => {
  if (url.indexOf('http') === -1) {
    return 'http://43.136.34.132:8088/' + url;
  }
  return url;
};
/**
 * 导出 excel 文件
 * @param dateString 2024-10-25 00:00:00
 * returns 2024-10-25
 */
export function formatTime(dateString: string) {
  // 使用正则表达式匹配日期字符串
  const match = dateString.match(/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/);
  if (match) {
    // 如果匹配成功，使用捕获组来构建新的日期字符串
    return `${match[1]}-${match[2]}-${match[3]}`;
  }
  // 如果匹配失败，返回原始字符串
  return dateString;
}

//格式化时间
export function formatDate(date: Date) {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
//计算传入天数相对当前时间的日期
export function calculateExpiryTime(currentTime: string, days: number = 1) {
  const date = new Date(currentTime);
  date.setDate(date.getDate() + days);
  return date;
}
//计算给定日期与当前日期之间的天数差
export function daysUntil(dateString: string) {
  const date = new Date(dateString);
  const now = new Date();
  const timeDiff = date.getTime() - now.getTime();
  const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
  return daysDiff;
}
//时间戳转日期
export function convertTimestampToDate(timestamp) {
  // 创建一个 Date 对象
  let date = new Date(timestamp);
  // 获取年份
  let year = date.getFullYear();
  // 获取月份（注意：getMonth() 返回的月份是从 0 开始的）
  let month = date.getMonth() + 1;
  // 获取日期
  let day = date.getDate();
  // 格式化日期，如果月份或日期小于 10，前面补 0
  month = (month < 10 ? '0' : '') + month;
  day = (day < 10 ? '0' : '') + day;
  // 返回格式化后的日期字符串
  return year + '-' + month + '-' + day;
}

// 格式化日期  2024年1月1日
export function formatDateText(date) {
  let year = date.getFullYear();
  let month = date.getMonth() + 1; // 月份从0开始，所以要加1
  let day = date.getDate();
  // 将月份和日期格式化为两位数，如果不足两位则在前面补0
  month = (month < 10 ? '0' : '') + month;
  day = (day < 10 ? '0' : '') + day;
  return year + '年' + month + '月' + day + '日';
}
/**
 * 导出 excel 文件
 * @param array JSON 数组
 * @param sheetName 第一张表名
 * @param fileName 文件名
 */
export function exportExcelFile(array: any[], sheetName = '结算', fileName = '结算明细.xlsx') {
  const jsonWorkSheet = xlsx.utils.json_to_sheet(array);
  const workBook: WorkBook = {
    SheetNames: [sheetName],
    Sheets: {
      [sheetName]: jsonWorkSheet,
    },
  };
  return xlsx.writeFile(workBook, fileName);
}
export const parseTime = (time?: object | string | number | null, cFormat?: string): string | null => {
  if (time === undefined || !time) {
    return null;
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date: Date;
  if (typeof time === 'object') {
    date = time as Date;
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time);
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(/-/gm, '/');
      }
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj: {[key: string]: number} = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value];
    }
    return value.toString().padStart(2, '0');
  });
  return timeStr;
};

// Format and filter json data using filterKeys array
export const formatJson = (filterKeys: any, jsonData: any) =>
  jsonData.map((data: any) =>
    filterKeys.map((key: string) => {
      if (key === 'timestamp') {
        return parseTime(data[key]);
      } else {
        return data[key];
      }
    }),
  );

/**
 * 身份证校验
 * @param idCardNumber string
 */
export function validateIDCard(idCardNumber) {
  const idCardPattern = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/;
  if (!idCardPattern.test(idCardNumber)) {
    return false;
  }
  const birthdate = idCardNumber.substring(6, 14);
  const year = parseInt(birthdate.substr(0, 4), 10);
  const month = parseInt(birthdate.substr(4, 2), 10);
  const day = parseInt(birthdate.substr(6, 2), 10);
  if (isNaN(year) || isNaN(month) || isNaN(day)) {
    return false;
  }
  if (month < 1 || month > 12) {
    return false;
  }
  if (day < 1 || day > 31) {
    return false;
  }
  if ([4, 6, 9, 11].includes(month) && day === 31) {
    return false;
  }
  if (month === 2) {
    if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
      return day <= 29;
    } else {
      return day <= 28;
    }
  }
  return true;
}

export const formatTimeHan = (date: any) => {
  let time = new Date(date);

  let y = time.getFullYear();
  let m = time.getMonth() + 1;
  let d = time.getDate();
  let h = time.getHours();
  let i = time.getMinutes();
  let s = time.getSeconds();
  return (
    [y, m, d].map((item) => String(item).padStart(2, '0')).join('') +
    [h, i, s].map((item) => String(item).padStart(2, '0')).join('')
  );
};

/**
 * @description 数字转中文数码
 *
 * @param {Number|String}   num     数字[正整数]
 * @param {String}          type    文本类型，lower|upper，默认upper
 *
 * @example number2text(100000000) => "壹亿元整"
 */
type ConfigType = 'lower' | 'upper';

interface Config {
  num: string[];
  unit: string[];
  level: string[];
}

interface Configs {
  lower: Config;
  upper: Config;
  decimal: {
    unit: string[];
  };
  maxNumber: number;
}

const confs: Configs = {
  lower: {
    num: ['', '一', '二', '三', '四', '五', '六', '七', '八', '九'],
    unit: ['', '十', '百', '千', '万'],
    level: ['', '万', '亿'],
  },
  upper: {
    num: ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'],
    unit: ['', '拾', '佰', '仟'],
    level: ['', '万', '亿'],
  },
  decimal: {
    unit: ['分', '角'],
  },
  maxNumber: 999999999999.99,
}

export const number2text = (number: number | string, type: ConfigType = 'upper'): string | false => {
  // 过滤不合法参数
  if (Number(number) > confs.maxNumber) {
    console.error(`The maxNumber is ${confs.maxNumber}. ${number} is bigger than it!`);
    return false;
  }

  const conf = confs[type];
  const numbers = String(Number(number).toFixed(2)).split('.');
  const integer = numbers[0].split('');
  const decimal = Number(numbers[1]) === 0 ? [] : numbers[1].split('');

  // 四位分级
  const levels = integer.reverse().reduce<string[][]>((pre, item, idx) => {
    let level = pre[0] && pre[0].length < 4 ? pre[0] : [];
    let value = item === '0' ? conf.num[Number(item)] : conf.num[Number(item)] + conf.unit[idx % 4];
    level.unshift(value);

    if (level.length === 1) {
      pre.unshift(level);
    } else {
      pre[0] = level;
    }

    return pre;
  }, []);

  // 整数部分
  const _integer = levels.reduce((pre, item, idx) => {
    let _level = conf.level[levels.length - idx - 1];
    let _item = item.join('').replace(/(零)\1+/g, '$1'); // 连续多个零字的部分设置为单个零字

    // 如果这一级只有一个零字，则去掉这级
    if (_item === '零') {
      _item = '';
      _level = '';

      // 否则如果末尾为零字，则去掉这个零字
    } else if (_item[_item.length - 1] === '零') {
      _item = _item.slice(0, _item.length - 1);
    }

    return pre + _item + _level;
  }, '');

  // 小数部分
  let _decimal = decimal
    .map((item, idx) => {
      const unit = confs.decimal.unit;
      const _unit = item !== '0' ? unit[unit.length - idx - 1] : '';

      return `${conf.num[Number(item)]}${_unit}`;
    })
    .join('');

  // 如果是整数，则补个整
  return `${_integer}元` + (_decimal || '整');
};
